from django.contrib.admin.views.decorators import staff_member_required
from django.shortcuts import render
from django.db.models import Count, Q, Avg, Max, Min
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
from django.contrib.auth.models import User
from datetime import datetime, timedelta
from .models import Battle, BattleStatistics, BattleRound
from codes.models import Code


@method_decorator(staff_member_required, name='dispatch')
class DashboardView(TemplateView):
    """综合仪表板视图"""
    template_name = 'admin/battles/dashboard.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        
        # 获取时间范围
        now = datetime.now()
        last_7_days = now - timedelta(days=7)
        last_30_days = now - timedelta(days=30)
        
        # 基础统计数据
        context.update({
            'total_users': User.objects.count(),
            'total_battles': Battle.objects.count(),
            'total_codes': Code.all_objects.count(),  # 管理员仪表板显示所有代码（包括已删除的）
            'active_codes': Code.objects.count(),  # 活跃代码数量
            'active_battles': Battle.objects.filter(status='running').count(),
        })
        
        # 最近7天统计
        recent_battles = Battle.objects.filter(created_at__gte=last_7_days)
        context.update({
            'recent_battles_count': recent_battles.count(),
            'recent_finished_battles': recent_battles.filter(status='finished').count(),
            'recent_avg_duration': self.get_avg_battle_duration(recent_battles.filter(status='finished')),
        })
        
        # 用户活跃度统计
        context.update({
            'active_users_7d': self.get_active_users(last_7_days),
            'active_users_30d': self.get_active_users(last_30_days),
            'top_players': self.get_top_players(),
        })
        
        # 对战结果分布
        context.update({
            'battle_results': self.get_battle_results_distribution(),
            'language_stats': self.get_language_statistics(),
        })
        
        # 最近对战列表
        context.update({
            'recent_battles': Battle.objects.select_related(
                'player1', 'player2', 'player1_code', 'player2_code'
            ).order_by('-created_at')[:10],
        })
        
        # 系统性能指标
        context.update({
            'avg_rounds_per_battle': self.get_avg_rounds_per_battle(),
            'max_battle_duration': self.get_max_battle_duration(),
            'error_rate': self.get_error_rate(),
        })
        
        return context
    
    def get_avg_battle_duration(self, battles):
        """计算平均对战持续时间"""
        durations = []
        for battle in battles:
            if battle.started_at and battle.finished_at:
                duration = (battle.finished_at - battle.started_at).total_seconds()
                durations.append(duration)
        
        if durations:
            avg_duration = sum(durations) / len(durations)
            return f"{avg_duration:.1f}秒"
        return "暂无数据"
    
    def get_active_users(self, since_date):
        """获取活跃用户数"""
        return User.objects.filter(
            Q(player1_battles__created_at__gte=since_date) |
            Q(player2_battles__created_at__gte=since_date)
        ).distinct().count()
    
    def get_top_players(self, limit=10):
        """获取顶级玩家列表"""
        # 基于胜率和对战数量的综合排名
        players = []
        for user in User.objects.all():
            stats = Battle.objects.get_player_stats(user)
            if stats['total_battles'] >= 5:  # 至少5场对战才参与排名
                score = stats['win_rate'] * 0.7 + min(stats['total_battles'] / 100, 1) * 0.3
                players.append({
                    'user': user,
                    'stats': stats,
                    'score': score
                })
        
        return sorted(players, key=lambda x: x['score'], reverse=True)[:limit]
    
    def get_battle_results_distribution(self):
        """获取对战结果分布"""
        results = Battle.objects.filter(status='finished').values('result').annotate(
            count=Count('id')
        )
        
        distribution = {
            'player1_win': 0,
            'player2_win': 0,
            'draw': 0,
            'error': 0
        }
        
        for result in results:
            distribution[result['result']] = result['count']
        
        return distribution
    
    def get_language_statistics(self):
        """获取编程语言使用统计"""
        # 统计代码语言使用情况（包括已删除的代码）
        lang_stats = Code.all_objects.values('language').annotate(
            count=Count('id'),
            active_count=Count('id', filter=Q(is_active=True, is_deleted=False)),
            deleted_count=Count('id', filter=Q(is_deleted=True))
        ).order_by('-count')
        
        # 统计对战中语言对决情况
        battle_lang_stats = Battle.objects.filter(
            status='finished',
            player1_code__isnull=False,
            player2_code__isnull=False
        ).values(
            'player1_code__language',
            'player2_code__language'
        ).annotate(count=Count('id'))
        
        return {
            'code_languages': list(lang_stats),
            'battle_matchups': list(battle_lang_stats)
        }
    
    def get_avg_rounds_per_battle(self):
        """获取平均每场对战回合数"""
        finished_battles = Battle.objects.filter(status='finished')
        if finished_battles.exists():
            total_rounds = BattleRound.objects.filter(
                battle__in=finished_battles
            ).count()
            return round(total_rounds / finished_battles.count(), 1)
        return 0
    
    def get_max_battle_duration(self):
        """获取最长对战持续时间"""
        max_duration = 0
        for battle in Battle.objects.filter(status='finished'):
            if battle.started_at and battle.finished_at:
                duration = (battle.finished_at - battle.started_at).total_seconds()
                max_duration = max(max_duration, duration)
        
        if max_duration > 0:
            return f"{max_duration:.1f}秒"
        return "暂无数据"
    
    def get_error_rate(self):
        """获取错误率"""
        total_battles = Battle.objects.count()
        error_battles = Battle.objects.filter(result='error').count()
        
        if total_battles > 0:
            error_rate = (error_battles / total_battles) * 100
            return f"{error_rate:.1f}%"
        return "0%"


@staff_member_required
def user_detail_dashboard(request, user_id):
    """用户详细信息仪表板"""
    try:
        user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return render(request, 'admin/404.html')
    
    # 获取用户统计信息
    user_stats = Battle.objects.get_player_stats(user)
    
    # 获取用户最近对战
    recent_battles = Battle.objects.filter(
        Q(player1=user) | Q(player2=user)
    ).select_related(
        'player1', 'player2', 'player1_code', 'player2_code'
    ).order_by('-created_at')[:20]
    
    # 获取用户代码（只显示未删除的）
    user_codes = Code.objects.filter(user=user).order_by('-created_at')
    
    # 计算对手统计
    opponents_stats = {}
    for battle in Battle.objects.filter(Q(player1=user) | Q(player2=user), status='finished'):
        opponent = battle.player2 if battle.player1 == user else battle.player1
        if opponent not in opponents_stats:
            opponents_stats[opponent] = {'wins': 0, 'losses': 0, 'draws': 0}
        
        if battle.result == 'draw':
            opponents_stats[opponent]['draws'] += 1
        elif (battle.result == 'player1_win' and battle.player1 == user) or \
             (battle.result == 'player2_win' and battle.player2 == user):
            opponents_stats[opponent]['wins'] += 1
        else:
            opponents_stats[opponent]['losses'] += 1
    
    context = {
        'user': user,
        'user_stats': user_stats,
        'recent_battles': recent_battles,
        'user_codes': user_codes,
        'opponents_stats': opponents_stats,
    }
    
    return render(request, 'admin/battles/user_dashboard.html', context)